package com.example;

import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.concurrent.EventExecutorGroup;
import org.junit.Test;

import java.net.InetSocketAddress;
import java.util.Date;

public class TimeServerNetty {
    @Test
    public void main() throws InterruptedException {
        //创建两个线程组,专门用于网络事件的处理，Reactor线程组
        //一个用来接收客户端的连接，
        //一个用来进行SocketChannel的网络读写
        NioEventLoopGroup boss = new NioEventLoopGroup(1);
        NioEventLoopGroup worker = new NioEventLoopGroup(10);

        ServerBootstrap bs = new ServerBootstrap();
        bs.group(boss, worker)  // 注册两个线程组
                .channel(NioServerSocketChannel.class)  //创建的channel为NioServerSocketChannel
                .option(ChannelOption.SO_BACKLOG, 1024)  // 设置TCP属性
                .childOption(ChannelOption.SO_KEEPALIVE, true)  //配置accepted的channel属性
                .childHandler(new ChannelInitializer<NioSocketChannel>() {  //处理IO事件的处理类，处理网络事件
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
                        ChannelPipeline p = ch.pipeline();
                        p.addLast(new TimeServerHandler());
                    }
                })
                .bind(new InetSocketAddress(9000))
                .sync()  //绑定端口后同步等待
                .channel()
                .closeFuture()
                .sync();  //阻塞
    }

    private class TimeServerHandler extends ChannelInboundHandlerAdapter {
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            ByteBuf buf = (ByteBuf) msg;//将msg转换成Netty的ByteBuf对象
            byte[] req = new byte[buf.readableBytes()];
            buf.readBytes(req);
            String body = new String(req, "GBK");
            System.out.println("The time server receive order : " + body);
            String currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body) ? new Date(System.currentTimeMillis()).toString() : "BAD ORDER";
            ByteBuf resp = Unpooled.copiedBuffer(currentTime.getBytes());
            ctx.writeAndFlush(resp);//只是写入缓冲区
        }
    }
}
